約 2,326,373 件
https://w.atwiki.jp/estorisetu/pages/42.html
※このTIPSはRO初心者または鯖新規向けに作成されています。 ※尚、拡張職については割愛します。 ※狩りを円滑に進めるには@go ☓や@loadをエモーションに登録したり、瀕死になったら無理せず脱出してヒーラーを活用しよう。 LV上げについて お金稼ぎについて その他・材料集め等
https://w.atwiki.jp/blackberrybold/pages/14.html
TIPS-アドレス帳で日本語入力できなくなる原因と予防方法 -変換時に候補が一つしか出てこない、予測変換がきかない -ショートカットキー -携帯電話への添付画像について -Microsoft Outlookとの同期について バグ報告-メディアプレーヤーで逆順再生されてしまう -電話アプリ起動直後は0キー入力不可になる TIPS -アドレス帳で日本語入力できなくなる原因と予防方法 原因:保存時にプロンプトをメアドなどの英語入力項目に置いたままにする 予防方法:保存時にプロンプトをタイトルや名前などの日本語入力項目へ置く 復帰方法:ショートカットで日本語を選択し直す -変換時に候補が一つしか出てこない、予測変換がきかない 復帰方法:トラブルが出た場合はバッテリーを抜き差ししてリブート (電源入れ直すだけでは解消しない) -ショートカットキー 参考サイト:黒と苺の BlackBerryBold日記 -携帯電話への添付画像について 携帯の場合、基本的にキャリアによって(BlackBerryやiPhone,Nokiaなどのスマートフォンを除き) 1回の受信容量に制限があります。 ソフトバンクは、本文と添付ファイルを合わせて 1)原則300k 2)大容量受信をオプション契約の場合1MBなどです。 http //mb.softbank.jp/mb/service/3G/mail/ docomoの場合は、機種によりますが、 1)原則20K 2)大容量対応機種の場合、合計2MB以内で最大10個まで。 http //www.nttdocomo.co.jp/service/mail/imode_mail/function/index.html#p02_01 -Microsoft Outlookとの同期について 同梱付属のCDからDesktopManagerをインストールしてください。 インストール~同期の際の注意点ですが、 PC側のユーザー名は、1バイト文字で登録してください。 インストール時は、PCがインターネットにつながっていることが必須です。 インストール時には、BB端末は接続しないでください。(予期しないエラー防止のため) 同期の設定は、PCとBBBをUSB接続した状態で、 Desktop ManagerのSynchronizeメニューをクリック → ConfigureメニューのSynchronaization からアプリケーションごと(連絡先、カレンダーなど)の設定と、 同期方向(双方向またはどちらか片方向か)の設定ができます。 バグ報告 -メディアプレーヤーで逆順再生されてしまう 再現手順:(A、B、Cという3曲があるとする)Cを再生中、ショートカットのPキーを2回押してBを再生すると、Bが終わってAが再生される -電話アプリ起動直後は0キー入力不可になる 再現手順:日本語入力モードの状態で電話ボタンを押し電話アプリを起動、0キーを押しても0を入力できない 回避方法:英文字入力モードにしておく or 最初に別の文字を入力し、それを削除してから0キーを押す ウェブ閲覧時にカーソルが虫眼鏡になるのを解除したいのですが、どのようにすればよいでしょうか。拡大しなくても良いページや、何か入力したいページのときに一回一回ズームされて非常に操作しづらいと感じます。宜しくお願い致します。 -- DDD (2011-08-11 23 16 56) 名前 コメント
https://w.atwiki.jp/high-wind/pages/22.html
システム、ToolのTips 画面解像度の設定の仕方 変則的な数値をいれることでワイド画面になり、横の視野が広がる。 .?FantasyEarthBeta?Settings?GLOBAL.INIファイル内の SCREEN_WIDTH=800 SCREEN_HEIGHT=600 ここの数値を変えます。 たとえば SCREEN_WIDTH=1024 SCREEN_HEIGHT=630 とかにしてみてください(Windowsのデスクトップの解像度が1024×768の場合)横の解像度をデスクトップの解像度と合わせる。 フルスクリーンモードでは起動しない。ウィンドモードで行う。 音楽の変更の仕方 Gamepot\FantasyEarthZero\data\WMA のファイルを入れ替えればおk。 以下、どのファイルがどの音楽に対応しているかのリスト。 m01.wma タイトル画面 m02.wma キャラクターセレクト m03.wma MAP選択 m04.wma フィールドA m05.wma フィールドB m06.wma 国内MAP m07.wma 戦争優勢 m08.wma 宣戦布告 m09.wma (欠番) m10.wma 戦争メインテーマ m11.wma 戦争劣勢 m12.wma 勝利テーマ m13.wma 敗北テーマ m14.wma ??? m15.wma ??? m16.wma フィールドC m17.wma ブリーフィングルーム m18.wma ??? m19.wma フィールドD m20.wma レベルアップ TS2話方のコツ いくらフリーハンドで楽に素早く意思を伝えられるとしても要点はあります。以下を心がけましょう。 曖昧な場所を伝えるのではなくはっきりと 今ここにいる、○のほう行く。では要点がつかめない。現在地を知らせる場合、どこかに向かう場合は座標をしっかりと伝える。 曖昧な方角を伝えない。 うしろ危ない!右から敵が来ている!これではどこの誰の後ろかわからない。無駄で誤解、混乱を招く。方角なり時計方式なりで統一し、誰でもすぐわかるようにする。 サブチャンネルなど便利なTS2の使い方 http //blog.miscast.org/archives/pc/teamspeak2/index.php? 2005年07月23日の記事を参照してください。 サブチャンネルを設定すればパーティーごとにサブチャンネルに入ることができて、会話の混乱がない。全体に話すなどのことも可能なので各Teamごとの連携もできる 各職業の戦術Tips 2hand Warrior 単発ヘビースマッシュはRootされた敵、迎撃等に。 ストライクスマッシュについて100%Hitが狙える状態。敵のステップ後、一拍置いて。 上り坂の時は何もしてなくても当たる。 敵のSkill発動に合わせて(これについては一概に100%とは言えない) コンボストスマ→スマ ストスマ→ヘビスマ(敵がステップしたら当たらない) ソニックブーム→ストスマ→スマ ベヒモス→スマ ドラゴンテイル→ヘビスマ ソニックブーム→ストスマ(敵ダウンorステップ)→ベヒモス(起き上がりorステップ後)→スマ(ベヒモスでダウンしなかったとき) Skillの特性を考慮すれば、色々つながるので自由に組み合わせることができる。Powと相談してよい組み合わせを。 戦略Tips
https://w.atwiki.jp/psemu/pages/105.html
公式Blog(最新Beta版のダウンロードはこちら) http //adripsx.blogspot.jp/ 旧公式サイト http //web.archive.org/web/20071201071652/http //adripsx.psxemu.com/ 2007/11/12のBeta版がUpされたngemu内のスレッド http //ngemu.com/threads/new-adripsx-release-here.95797/ 2007/11/12版 http //wayback.archive.org/web/*/http //www.kaze-net.com/Downloads/New%20AdriPSX.zip
https://w.atwiki.jp/gkk_wiki/pages/11.html
はじめに 外国語 お肉の楽な売り方 紙の楽な買い方 キーボード 再インストール後の設定 日本語入力で文字化け はじめに このページはTipsです.ちなみに”てぃぷす”と読みます. 日本語に訳すと裏技って意味だったかなぁ・・ Gunzをやってて気づいたこととか載せていこうと思っています. このページのトップへ 外国語 皆さんもご存知のようにこのクランには何人か外国人が在籍がいます。 そこで、彼らとコミュニケーションが取れるように各国語の挨拶をまとめてみました。 さぁ、これであなたもレッツ異文化コミュニケーション! 日本語 英語 ドイツ語 スペイン語 おはよう Good morning Guten Morgen Buenas dia s こんにちは Hello Guten Tag Hola こんばんは Good evening Guten Abend Buenas noches さようなら Good bye Auf Wiedersehen Adios ありがとう Thank you Danke Gracias 当然のことですが、外国で話す時は半角ですよ しかし、こうして挨拶してしまうと「お、こいつ英語話せるな」と思われべらべらしゃべられてしまい困るという方のために素敵な台詞を教えましょう。 私は○○語が苦手です。 My English(German,Spanish) is very poor...( _ ) このページのトップへ お肉の楽な売り方 生肉(x99) 焼いた肉(x99) ........ ........ クエラーの皆さんなら誰もが見たことのあるこの画面,お肉等のクエストアイテムはすぐに99個になってしまい.しかも99個以上持てないので99個持っている状態でクエストしてもお肉がそれ以上手に入らないという困ったことになってしまいますよねw そして,お肉を処分するために商店に売るんだけど売るときに▲ボタンを連打しながら,「あぁ,数値入力とかでもうちょっと楽に売れるようにならないかな〜」なんて思ったことがあると思います. そこでいろいろ試してみました. すると・・なんと楽に売る方法があったのですよ!紹介していきたいと思います. まず,いつものように商店に行きます.肉を売ろうとすると”売却する数量を入力してください.”っとっ表示されますよね.そして,ここからがTipsです. 1.売却数の▲ボタンをマウスで一回クリック 2.エンターキーを押す(押しっぱなし) 3.売りたい数で止めて,マウスで数を微調整する 4.”売却”ボタンを押す 5.おわり どうです?楽に売れたでしょう? このページのトップへ 紙の楽な買い方 クエラーの皆さんなら一度は思ったことのあるであろうこと,その2「破られたページをさっさと飼いたいなぁ」 思いますよね? ではさっそくTips 1.破られたページを選択する 2.エンターキーを押しっぱなしにする 3.購入ボタンを押す 4.おわり 1〜3を繰り返すだけです. どうです?早いでしょう? このページのトップへ キーボード 私(編集者)が実際に使ってみたり,店頭で試したキーボードでちょっと気になったものを載せておきます.価格,インターフェイス等はそのキーボードの載ったサイトのリンクをキーボードの型番のところに張っておくので,そちらを参照してください. メーカー 型番 その他説明など ELECOM TK-UP87MPBK パンタグラフだけど,ノートパソコン程キータッチは軽くない.使わないときに立てて置けるのが便利でした. BUFFALO BKBC-J91SBK ノートパソコンとほぼ同様のキータッチを持つパンタグラフキーボード.コンパクトで好きだった. PFU PD-KB220W/P コンパクトキーボードでありながら,フルキーボード.パンタグラフが好みではなく,コンパクトキーボードならコレがオススメ.USBタイプはUSBのハブも内蔵しているので便利. DECA DSKB-106W 一般的なパンタグラフキーボード.テンキー付き FILCO FKB108Z/JW パンタグラフではないが,非常に軽いキータッチをもつフルキーボード.押す時のカチカチ感がイイです. このページのトップへ 再インストール後の設定 GunZが最近なんか変!?って時は再インストールすると直ることがあるのは皆さんご存知のはず. そして,その再インストールの際に失うもの・・・それは”エフェクトクオリティ:高い”とかの自分のオリジナルの設定.特にマウスの感度の設定は変わるとAIMingに支障をきたすため,避けたいはず. そこで,役に立つのがこのTips,自分の設定ファイルを残したままGunZのみを新しいのにできるんですよ. では,前置きはこのくらいにしてTips行ってみよう~!! 1.GunZをインストールした場所に移動.デフォルトインストールではC \Program Files\NetmarbleJP\Gunz\ 2.そこにconfig.xmlというファイルがある,実はこれが自分のオリジナルの設定が書かれてるファイル.XMLファイルなのでもちろん編集することも可能.GunZ内のオプションは実はこのファイルを書き換えているだけ. 3.config.xmlを別の場所(デスクトップなど)にコピー.いわゆるバックアップを取る. 4.C \Program Files\NetmarbleJP\以下を全て削除する. 5.GunZをダウンロードし,インストールする. 6.GunZをインストールした場所(デフォルトインストールではC \Program Files\NetmarbleJP\Gunz\)に移動し,3.でバックアップを取っておいたconfig.xmlを新しいconfig.xmlと置き換える.この際,念のため新しいconfig.xmlをconfig.oldなどと名前を変えて一応保管しておいたほうが無難. 7.GunZを起動し,動作確認. このページのトップへ 日本語入力で文字化け GunZで日本語入力をするとき文字化けして困っていませんか?普通にチャットしているだけなのに「・」や文字コードにない変な文字がついてしまうと萎えますよね〜?部屋に入るたびに「文字化けすみませ〜ん」なんて言ったりするのも面倒ですし・・何かと格好がつきませんよね. そこで今回その場合の直し方を説明しようと思う〜.情報提供はららん♪さんです. 1.タスクバー内にあるIMEパッドを右クリック(言語バーの復元をしていた場合は画面上に表示される言語バー) 2.右クリックでメニューが出てくるので[設定]をクリック. 3.[テキスト サービスと入力言語]ウィンドウが開くので,[詳細設定]のタブをクリック. 4.[システムの構成]枠の中に[高度なテキストサービスをオフにする]というチェックボタンがあるのでチェックをいれる. 5.[適用]を押し[OK]で[テキスト サービスと入力言語]のウィンドウを閉じる. 6.GunZを起動し,動作確認.この方法で直らなかったらIME以外のものが原因の可能性が高い. ※GunZの公式ページにも書いてあるようです. このページのトップへ
https://w.atwiki.jp/kenust/pages/30.html
OSI参照モデル 7階層アプリケーション層 具体的な通信サービスを提供。(例えばファイル・メールの転送、遠隔データベースアクセスなど)HTTP, SMTP, SNMP, FTP, Telnet, X.500等の通信サービス。 6階層プレゼンテーション層 データの表現方法。(例えばEBCDICのテキストファイルをASCIIコードのファイルへ変換する)SMTP, SNMP, FTP, Telnet, AFP 5階層セッション層 通信プログラム間の通信の開始から終了までの手順。(接続が途切れた場合、接続の回復を試みる)NetBIOS, NWLink, ASP, PAP, 名前付きパイプ 4階層トランスポート層 ネットワークの端から端までの通信管理。(エラー訂正、再送制御等)TCP, UDP, NetBEUI 3階層ネットワーク層 ネットワークにおける通信経路の選択(ルーティング)。データ中継。IP,IPSec, ICMP, DHCP, IPX, NetBEUI 2階層データリンク層 直接的(隣接的)に接続されている通信機器間の信号の受け渡し。PPTP, イーサネット, トークンリング , PPP, フレームリレー 1階層物理層 物理的な接続。コネクタのピンの数、コネクタ形状の規定等。銅線-光ファイバ間の電気信号の変換等。RS-232, RS-422(EIA,TIA), 電話線・UTP, ハブ, リピータ, 無線, 光ケーブル
https://w.atwiki.jp/weboo/pages/27.html
情報を脈絡もなく書いてみるべ 個人商店 アシスト 鍛錬 長くなったので別ページ Tips/パーティ(PT) Tips/チャット Tips/設定紹介 Tips/変換落ち対策 Tips/その他 名前 コメント すべてのコメントを見る らりすけさんからの情報>稲妻のパラディンハンマーで鍛錬5→6の強化時に>クリティカルも上昇もしも陽炎や月光なら・・わくわく-- (うえぶぅ) 2006-07-30 19 28 54 Tipsコメントテスト -- (うえぶぅ) 2006-07-28 17 04 39 個人商店 露天キャンセルの時はEcsキーを使用する癖をつけるといいんじゃよ誤購入防止はもちろんとバグによる何度も開く現象が多少は緩和されますじゃぁ アシスト 「アシスト使えねー」って聞いてたので使ったことなかったけど、 機会があったのでためしてみた。 アシストの相手が”攻撃中”でないとタゲ移らないね。 んで、どうやったら使えるか試行錯誤したところ、 アシストをスペースキーに割当(チャットはEnter) 考えた手順も書いてみるだよ。 ファンクションキーでパーティメンバーの TargetLeader をタゲ FirstAttackで敵にタゲが移るようにスペース(アシスト機能)連打 視界にいなくてもok タイミングを逃したら普通にtabでタゲ 実験協力者>タイミング的に攻撃発動が少し遅れるようです。 上の手順が”キッチリと”できてたら、tabと同じか早めに 攻撃開始できそうですじゃ。 ・・・どうせ私は順応遅いですよ、ふん! orz 鍛錬 ウワサ幸運の~では成功したことないってやつは不運の~をつけてやってみるといいことあるかも? +4以上にするには20個用意して一気にしたほうがいい。 ようお越しぃ [PR] インターネット広告
https://w.atwiki.jp/hmiku/pages/3049.html
【登録タグ 作T 作TQ-T 作り手】 【ニコニコ動画】作品集 特徴 トランス調ポップを得意とするP。 映像や音楽などを表現のエレメントとして捉え、そこから生まれるストーリー性を重視した高尚な創作活動をしている。 何と楽曲製作からPV製作までの作業を全てを一人でこなしている。 独自で3DCGミクのモデリング(Tripshots式初音ミク3Dモデル)を製作、そのデータをHPにてフリー配布しています。 革新的な技術を用いた「ほうき星3DPV」はリリース当時としてはあまりにも衝撃的であり、それを切っ掛けにブレイク。 「Extended-ゆっくり-」は3DPVではなく2DのPV仕様。 「Nebula」PVではTripshots式初音ミク3Dモデルを一新。以前のとは全く別物になってます。 その完成度はまるでモデル自体が生きていて子供から大人へ成長したような錯覚に陥るほど。さらに質感も戦慄レベル… リンク 作者ホームページ(Tripshots) PIAPRO ボーカロイドにゃっぽん YouTube(Tripshots Channel) 曲 anger Extended-ゆっくり- forbidden fruit/Tripshots Genesis/Tripshots gift nor art Nebula CD Another Dimensions Digital Trax presents VOCALO★POPS BEST feat. 初音ミク EX P~Ex Producers~ future/TripshotsCD Genesis/Tripshots hammer2 Nebula/CD Synthesis/CD VOCALO DANCE feat.初音ミク -ベスト・アゲ!トラックス- 初音ミク Vision 初音ミクDVD~memories~ ボカロ超ミックス39 feat. 初音ミク 動画 コメント 神だといいたい -- 名無しさん (2009-07-26 13 14 45) なぜにコメント少ない。 もっと評価されるべき。 -- あゆみ (2009-11-14 21 32 32) この人は化け物か・・・?尊敬を通り越して恐怖すら覚える -- 名無しさん (2010-04-22 21 26 42) Tripshots様は一つ一つの曲の感動というものをすごく大切にしていらっしゃると思います。 -- 雲来三琴 (2012-08-07 12 48 16) この方は凄すぎてちょっとうまく形容する言葉が無いです。「gift nor art」を初めて見た時は開いた口がふさがらず、ただ呆然と見入ってしまいました -- 名無しさん (2013-06-25 00 29 25) 曲も映像もすごすぎる!大好きです -- 名無しさん (2013-10-04 16 42 55) 映像のクオリテイがすごすぎる・・・ -- 名無しさん (2014-08-07 23 41 21) 名前 コメント
https://w.atwiki.jp/skyrim_mod/pages/18.html
ここではスクリプトの小技やタメになる情報を扱います。 スクリプト作成時の注意点初心者はSE版のみ対応として作成を行う事(慣れるまでLE・SE両用を作成しない) アルゴリズムを組む前にSKSEプラグインを確認する コンソール経由でしか処理できないものもある デバッグのためエフェクトや状態をコンソールから確認できる環境を整える Papyrusでキー入力系のスクリプトを作成する時は高速なレスポンスを求めた処理は望まない 戦闘が絡むスクリプトの動作確認について大規模戦闘下での確認は行う事 ニューゲーム、途中導入での動作確認は怠らない (SE版のみ)Papyrusに慣れたらSkyrim Platformでのスクリプト開発を検討する 予約語self 否定の "!" 関数の処理について イベントの処理 スクリプト最適化Tips重複処理をさせない→Stateを使う(スタックエラーの防止策) return文で処理を中断する None(エラーを少なくする方法)Noneを代入して完全に消す 同じアクセサ関数(Get~系)を複数回使用しないこと。 変数はローカルで保持する Is3Dloaded() 引数が多い関数やイベントほど重い 安易なスクリプト使用の代替回避をしない WhileとWaitによる処理及び処理待ちの多用は厳禁 スクリプト最適化実践編装備時のイベント重複防止 OnHitの重複防止 スクリプトログをとる(デバッグの仕方)スクリプトログの設定 LogExpertを導入 スクリプトにデバッグ情報の記載 OnAnimationEventで取得できるイベント AnimationVariableの使い方さまざまな状態の判定 iStateの変数 セーブデータに残るもの不必要になったプロパティの削除 SM Eventを使ったRepeatQuest セル移動時関係のイベント NPCへのPerk付与について Perkの挙動について特定行動時にスペル付与系 Add ValueやSet Value等の数値変動系の計算の優先度 IsInKillMove関数の注意点 スクリプトによる一部のフォームの値変更について ConsoleUtilによるターゲットコマンド実行の注意点及び安全な実行について負荷が掛かると誤実行される危険性がある 対策 アビリティ付与に関する注意 Activate関係の処理についてBlockActivation関数でアクティベートをブロックしてもOnActivateイベントは発生する パークのアクティベート処理変更についての注意点OnActivateイベントが発生しない BlockActivation関数でアクティベートのブロックをしても処理が実行される スクリプト側でアクティベートした場合は動作変更が行われない 対処法のサンプル スクリプト作成時の注意点 初心者はSE版のみ対応として作成を行う事(慣れるまでLE・SE両用を作成しない) SE版が販売して数年はSKSEの更新等で不安定だった事もありLE版が主流でしたが、現在はSE版の販売から10年以上経過しており環境が比較的安定したため、SKSEプラグイン等のModリソース開発者の多くがSE版に移行しています。 それに伴いSPID等、Mod作成用のリソースがLE版での更新がされなくなっている、またはSE版のみリリースしてる所が多くなっているため、LE版と比較してSE版の方が開発リソースは豊富となっています。このため、LE版で高度な事をやりたい場合、特にLE・SE版両用を行いたい場合は作成のハードルが高くなります。 (特にこのwikiでも紹介しているPapyrus関数拡張SKSEであるpowerofthree's Papyrus ExtenderはLE版の更新が2020/07/08が最後となっており、当然SE版と比べてやれる事が少なくなってます) また、慣れない内にLE・SE両用のMod作成をした場合、配布後のトラブル対応に苦労する可能性があるため初心者はSE版のみの開発をオススメします。 アルゴリズムを組む前にSKSEプラグインを確認する アルゴリズムを組む前に、wikiメニュー一覧の「SKSEプラグイン」に記載されてる「主なPapyrus関数拡張SKSE」のSKSEをダウンロードし、それのソースを確認して実現したい処理がそのSKSEが提供しているPapyrus関数一つで行えるかを確認しましょう。 (例としてInt型をstring型に変換、string型の数値をInt型に変換する処理を作りたい場合、自前でアルゴリズムを組もうとするとかなり手間が掛かりますが"powerofthree's Papyrus Extender"のIntToString、StringToInt関数を用いる事で容易に実行可能でかつ自前でアルゴリズムを組んだ処理よりも高速に処理できます) また、アクターやオブジェクトの状態の操作や確認、アクターやフォームの一覧を取得したい場合は"powerofthree's Papyrus Extender"、AIパッケージ上書きやファイル関連の操作は"PapyrusUtil"を使用する事で大抵の事はできます。 まずはこの2つだけでもダウンロードしてどのような処理が行えるか把握しておくと良いでしょう。 コンソール経由でしか処理できないものもある Papyrusで実行したい関数が無かった場合はコンソールコマンドも確認するようにしましょう。 例えばレベル設定はPapyrusではプレイヤーのみしか行えずNPCに対してはコンソールコマンドでしかレベル設定はできません。 SKSEプラグインのConsoleUtilを利用する事でPapyrus経由でのコンソールコマンドの実行が可能となります。 (ConsoleUtilは指定した文字列をコンソールに出力する関数があるため、デバッグ等でも便利です) コンソールコマンドの表については以下のサイトが参考になります。 https //www.creationkit.com/index.php?title=Category Console_Commands https //elderscrolls.fandom.com/wiki/Console_Commands_(Skyrim) https //en.uesp.net/wiki/Skyrim Console デバッグのためエフェクトや状態をコンソールから確認できる環境を整える LE版はMfg Console、SE版はMore Informative Consoleを導入すれば、コンソール画面で対象を選ぶだけで対象の状態の確認が行えるようになります。 アビリティは付与されたけどマジックエフェクトがアクティブになってない等の確認も簡単に行えるようになるのでデバッグが非常に容易になります。 Papyrusでキー入力系のスクリプトを作成する時は高速なレスポンスを求めた処理は望まない キー入力後からの判定や処理は冗長化しないように可能な限り最適化するように心掛けましょう。これを怠るとキー入力直後に処理を実行したいのに入力後しばらくした後に処理が実行されるという事が起こります。 PapyrusはSkyrimのバックグラウンド処理の仕組み上の問題からどのように最適化しても基本的には僅かでも遅延は起こりえるという事を念頭にスクリプトを作成してください。 また、『敵の攻撃がヒットする直前に特定のボタンを押せば相手の攻撃をキャンセルor自身を無敵化させてダメージ無効化』のような非常に早いレスポンスが求められるものはPapyrusだけで実現するのはまず不可能です。 実際にやろうとすると「判定処理→判定成功→相手の攻撃キャンセルor無敵処理」の判定成功からの判定成功後処理を行う直前で攻撃を受けてしまい、その後に判定成功後の処理が実行されるという事態がよく起こります。 (特にスクリプトのスタックが発生しやすい大規模戦闘では判定処理成功→攻撃を受ける→1秒以上経過した後に判定成功処理が行われるという事態が起こります) 高速なレスポンスを要求されるModを作成したい場合はSKSEプラグインを作成するか、Skyrim Platformでスクリプトを作成してください。 戦闘が絡むスクリプトの動作確認について大規模戦闘下での確認は行う事 数人程度の敵と戦闘して問題ない事があっても内戦などの大規模戦闘ではスクリプト遅延の多発は容易に起こります。 このため、戦闘関連のスクリプトの動作確認は数人程度の敵と戦闘して問題ないか確認した後、大規模戦闘で動作に支障が無いかの確認をしましょう。 負荷テスト確認を行う場合は事前に「ホワイトランの戦い」等の大規模戦闘前のセーブデータを用意しておくと確認しやすくなります。 また、Assault on ValenwoodというModは内戦クエスト以上の大規模戦闘かつ開始が非常に容易のためこちらを導入しての確認もオススメです。 ニューゲーム、途中導入での動作確認は怠らない ニューゲームで開始時、ゲーム途中からのMod導入どちらでも動作に問題ないか念の為確認しましょう。 スタート地点変更Modがあると確認がしやすくなります。 (SE版のみ)Papyrusに慣れたらSkyrim Platformでのスクリプト開発を検討する 開発環境の構築に手間が掛かりますが、Skyrim Platform(SP)で開発が行えるならばスクリプト作成はこちらで作成したほうが良いです。理由として SKSEプラグインのDLLがスクリプトを読み込んで実行するという形なのでPapyrusの数十倍処理が高速 特定の処理で実行しない限りはバックグラウンドでは実行せず、フォアグラウンドで実行されるため高速なレスポンスを求められる処理を作成可能 Papyrusだと処理件数が非常に多くなると一部の処理を後回しにしてしまい、結果スタックが溜まって処理が遅れる(そしてそうゆう状況下だと高確率でまずスタックがどんどん貯まる可能性が高いため最悪フリーズという事態になる)がSkyrim Platformでは処理の後回しによる遅延はなく、仮に処理件数が膨大だった場合でも処理落ちという形で処理遅延の回避が可能となる ゲーム中にスクリプトを編集可能、編集内容の反映が可能でデバッグが非常に容易 とPapyrusでのスクリプト作成よりも遥かに利点が多いです。 Skyrim Platformのスクリプト関数はPapyrus関数を準拠にしておりPapyrusで実行できる関数のほとんどが実行可能(開発途中のため一部の関数で確定CTDするため注意)、 さらにSKSEプラグインのPapyrus関数拡張SKSEの関数も定義ファイルを作成すればSkyrim Platform上で実行可能とPapyrusでの経験も応用しやすいためPapyrusに慣れたらSkyrim Platformのスクリプト作成も検討しましょう。 予約語self 予約語は役割が予め決まっており変数で使用できない語です。 selfはそのスクリプトをつけているオブジェクトそのものを指します。 例えばリディア(Actor)についているスクリプトの場合はselfが指すのはリディア(housecarlwhiterun)です。 わざわざプロパティ作ったり変数作ったりしなくていいのできれいにコードが書けます。 self.GetDistance(player) ;リディアとプレイヤーとの距離を測ったり Debug.SendAnimationEvent(self,"attackStop") ;リディアに攻撃停止のモーションを送ったりできます 他にもActiveMagicEffectにつけたものでその魔法効果を消す場合は self.dispel() クエストにつけたものでそのクエストを停止させるには self.stop() このように幅広く使えます。 否定の "!" スクリプト上で!をつけると~でないという否定の意味になります。 !Actor.IsSprinting() ;スプリント中でない、Actor.IsSprinting() == falseと同じ。 !(Actor.GetEquippedItemType(1) == 0) ; 右手の武器が素手ではない Actor.GetEquippedItemType(1) != 0と同じ 関数の処理について 関数の処理の仕方についておおまかに3つに分類します。 1.同期が必要なLatent Function スクリプトは上から順に処理していきますが、関数の中でも処理が終わるまでスクリプトが止まるのがLatent Functionです。 代表的な例はWait()です。 Utilty.Wait(1.0)なら1秒経過するまでWaitの部分でスクリプトは待ってます。 次にCast関数です。 これも実際に画面上で魔法が放たれるまで待ってます。 しかし、ノーモーションで魔法が放たれるので、非常に処理が速いです。 CK wiki内のリストには入ってませんがFind系の関数は値が返ってくるまで待ち、処理が遅いです。 2.非同期処理の関数 これは関数の実行が終わったかどうかは関係なく、処理の手続きをしたらさっさと次に進む関数です。 モーションを再生するPlayIdle()がそうです。 モーションが終わったかどうかは関係なく次に進みます。 SoundのPlay()なども同じく、処理の手続きすればすぐ次に行きます。 これと同じ機能で同期処理版がPlayAndWaitです。 スクリプトではなく実際の処理自体はフレームレートやPCの性能に左右されます。 手続された順に再生されるので画面上では遅延が起きるかもしれません。 ※仮説上の話ですが、パピルスが言語として遅いのは画面と同期するために意図的に遅くしている可能性も。 3.画面と同期する必要のないNon-delayed Native Function 画面で起こってることとは全く関係ない、MathやRegister系の関数などです。 これらの関数はフレームレートに左右されずに、常に高速で動きます。 3.以外は1.だから速いとか2.だから遅いというわけではなく、個々での関数で速度を勘定したほうがいいでしょう。 イベントの処理 同一のフォーム内のスクリプトではイベントのフラグは同時に受けとります。 たとえば、クエスト1に対してスクリプトA・スクリプトBをつけ、 ;スクリプトA Event OnInit() RegisterForSingleUpdate(1) EndEvent Event OnUpdate() Debug.trace("Script A") EndEvent ;スクリプトB Event OnUpdate() Debug.trace("Script B") EndEvent どっちのOnUpdateも動きます。 OnUpdateを別に動かしたい場合は、クエストを別にするか、Stateを使ってうまく振り分けましょう。 また、別のスクリプトが誤作動してしまうために、スクリプトをアクターにつけず、基本的に独立しているMagic Effect使います。 スクリプト最適化Tips エラーの少なく、処理の早い書き方があります。 原則 イベントも関数も呼び出しが少ないほうがよい なので重複処理を防止したり、繰り返しの処理をまとめたりが重要です。 重複処理をさせない→Stateを使う(スタックエラーの防止策) 敵から攻撃受けた時に両手武器の場合はスタミナに5ダメージという仕組みに加えて、 一度イベントが起きたら0.5秒間同じ処理をさせたくない場合です。 Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) ;攻撃者がいない場合、ダメージソースが武器以外の場合は即処理中断 if akAggressor == None || !(akSource as Weapon) return endif ;BusyのStateに飛ばす GotoState("Busy") ;武器の種類を取得 int WeapType = (akSource as Weapon).GetWeaponType() ;両手剣または両手斧槌ならば if WeapType == 5 || WeapType == 6 Game.GetPlayer().DamageAV("Stamina",5.0) endif ;重複防止のために0.5秒待機 Utility.Wait(0.5) ;Stateを元の状態に戻す GotoState("") EndEvent State Busy ;StateがBusyの時はOnHitイベントが起こっても何も処理しない Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) EndEvent EndState Stateはその名のとおり状態を表してまして、指定したState中にイベントが起こった場合は、Stateに記述したイベントが優先されます。 例のスクリプトはGotoState()で"Busy"というStateに移動します。Stateが変わっても元のOnHitイベントは継続して処理が進みます。 この間にOnHitイベントが起こっても、すべてState Busyの方で処理されます。最後に空のStateにGotoStateで戻って、また通常のOnHitイベントが起きるようになります。 スタックエラーは特定の条件下で、何回も処理が動いてしまうのが原因の一つなので、Stateを使って複数回処理するのを制限することで回避できます。 return文で処理を中断する returnは本来、戻り値を返すためのものですが、実行されると、実行中のイベントや関数から強制的に中断します。 OnHitなどの頻繁に動くイベントの場合は、条件に合わない処理を事前にreturnで中断させるのは非常に有効です。 ダメな例 Event SomeEvent() bool keepRunning = true If someCondition1() keepRunning = false ElseIf someCondition2() keepRunning = false EndIf If(!keepRunning) DoStuff() EndIf EndEvent 良い例 Event SomeEvent() If someCondition1() || someCondition2() return EndIf DoStuff() EndEvent 悪い例ではkeepRunningを代入したり、チェックしたりの分の処理してますが、 良い例では条件が合わない場合は即処理を中断します。 Stateとreturnを組み合わせる場合は、returnで中断されるとStateが戻ってこれなくなるので、 GotoState前に書くか、return前にGotoState("")で抜け出します。 if return endif GotoState("Busy") if GotoState("") return endif None(エラーを少なくする方法) スクリプトが対象のオブジェクトが見つけれない時にエラーになりますが、これがエラーの中ではもっとも多いかと思います。 None Object、 has no 3d 基本的にスクリプトエンジンはこのエラーを無視するので問題無いですが、エラーログ出すぎると重くなったり不安定になったりする可能性があるのと、ログが読みにくくなるのでその対処法です。 オブジェクトがない状態をオブジェクトはNoneと返します。 また、不必要になったオブジェクトにはNoneを代入すると安全です。 if PlayerRef != None ; プレイヤーのリファレンスがないときは処理を行わない ..... endif もしくは if PlayerRef == None ; プレイヤーのリファレンスが取得できない時はリターンでイベントの強制終了。 return endif Noneを代入して完全に消す ObjectReferenceやFormのデータはDeleteを使っただけではスクリプト上では完全に消えてないので、 これを解放するにはNoneを代入する必要があります。 ObjectReference Box = PlayerRef.placeAtMe(FXEmptyActivator) ;透明オブジェクトを置く Box.MoveTo(PlayerRef, 0, 50, 85) ;透明オブジェクト移動 Box.Delete() ;透明オブジェクトを削除 Box = None ;Deleteでゲーム上からは消えますがスクリプトでは残っているのでNone入れて、ないことにする。 同じアクセサ関数(Get~系)を複数回使用しないこと。 アクセサ関数はなにか取得する(Get~)関数です。Game.GetPlayer()だとか、GetTargetActor()ですね。 ダメな例 Event SomeEvent() GetTargetActor().AddItem(coolItem, 1) GetTargetActor().AddSpell(coolSpell) GetTargetActor().Kill() GetTargetActor().Resurrect() EndEvent なぜダメかといえば、毎行たびにGetTargetActor()の処理を行い、取得しているからです。 つまり例では4回処理してます。 はじめの一行でGetTargetActor()を取得して変数に代入し、あとはそれを当てはめたほうがコードの見通しもよく効率的です。 よい例 Event SomeEvent() Actor selfActor = GetTargetActor() selfActor.AddItem(coolItem, 1) selfActor.AddSpell(coolSpell) selfActor.Kill() selfActor.Resurrect() EndEvent 例外としてはGetTargetActor()の使用が1回だけの場合にはselfActor等の不必要な変数を追加する必要はなく、以下のが効率的です。 GetTargetActor().AddItem(coolItem, 1) 変数はローカルで保持する 不必要な静的変数を設定しないことです。 ダメな例 int onHitVariable ;OnHitイベントで使う変数 int onDeathVariable ;OnDeath event int bothEventsVariable ;両方のイベントで使う変数 Event OnHit( parameters ) DoStuffWith(onHitVariable) DoStuffWith(bothEventsVariable) EndEvent Event OnDeath( parameters ) DoStuffWith(onDeathVariable) DoStuffWith(bothEventsVariable) EndEvent 良い例 int bothEventsVariable ;両方のイベント間で使う変数は静的変数としてイベント外で定義しておく Event OnHit( parameters ) int onHitVariable ;OnHitでしか使わない変数はOnHit内で定義 DoStuffWith(onHitVariable) DoStuffWith(bothEventsVariable) EndEvent Event OnDeath( parameters ) int onDeathVariable ;OnDeathでしか使わない変数はOnDeath内で定義 DoStuffWith(onDeathVariable) DoStuffWith(bothEventsVariable) EndEvent Is3Dloaded() 3Dデータとして読み込まれているかどうかの判定をする関数で、has no 3d~のエラー対策に使えます。 インベントリに回収しちゃって処理ができない場合や、ラグがあって3Dオブジェクトが設置される前にスクリプトが稼働した場合にhas no 3dのエラーがでます。 If self.Is3Dloaded() == True ;3Dデータが読まれているなら処理 Endif ラグ防止の場合:3Dデータが読まれるまで待機 int i = 10 ;時間切れを10秒に設定 While self.Is3Dloaded() == False i 0 ;3Dデータが読み込まれるか時間切れまで待つ Utility.Wait(1.0) i -= 1 EndWhile 3Dデータが必ず読み込まれるという保証はないため、タイムアウトを設定するのは極めて重要です。 引数が多い関数やイベントほど重い パピルスの仕様で、引数から変換するときの処理が重いのです。したがって引数が多いほど重いので OnHitイベントやFind~()は重いです(OnHitは頻発するのとFindはそもそも探索が遅いのあります)。 別のイベントや関数で代替できるならそちらでしたほうが良い場合もあります。 安易なスクリプト使用の代替回避をしない スクリプト使わないパターンでよくあるのが魔法のアビリティのコンディションで代替するパターンでこれは極めて悪手です。 スペルのアビリティのコンディションは毎秒条件の判定があるのでスクリプトで毎秒ループしてるのと同じぐらい重いです。 スクリプトのループと違って、papyrusログにスタックエラーが出ないのでより悪質です。 素直にスクリプト使ってイベント駆動型にしたほうが断然軽く安定します。 WhileとWaitによる処理及び処理待ちの多用は厳禁 以下のようにWhileとWaitを用いる処理について、Quest等の単一のスクリプトで行う場合ならまだしも、多数のアクターにアビリティを付与して以下のWhileとWait処理を行う場合は状況によってはスタックが溜まってしまい処理遅延発生の元になってしまいます。特に大規模戦闘等のアクターが大勢いる状況だと処理遅延の多発が起こり、最悪CTDが起きる可能性が高まるため注意が必要です。(例としてはEnhanced Blood Textures。アクターの死亡時で以下と同じような処理を行っている) int i = 0 while i 100 ; ループ処理 ~ 省略 ~ Utility.wait(1) i += 1 endWhile 多数のアクターでどうしてもこのような処理を使用する必要がある場合は、GlobalVariable等にWhile&Wait処理を行っているアクターの総数を記録しておき、処理を行える人数を制限するか、一定数存在したら処理の中断を行うようにする事。(演出系の場合はHasLOS等でプレイヤーが視認できない場合は処理を省略する等を行う) ;一例、GlobalVariableで処理人数を記録して処理可能人数を制限する if GlobalVariable.GetValueInt() 5 GlobalVariable.Mod(1) int i = 0 while i 100 ; ループ処理 ~ 省略 ~ Utility.wait(1) i += 1 endWhile GlobalVariable.Mod(-1) endif スクリプト最適化実践編 装備時のイベント重複防止 OnObjectEquippedは何か装備したときに発動するイベントですが、 一つのアイテムにもかかわらず、6回以上(特にエンチャント武器)呼び出されたりするうえ、対処が厄介です。 例では武器装備時に処理したい場合です。 Form PreObj = None Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference) ; ベースオブジェクトが取得できない、エンチャント、装備が前と同じ場合は何もしない if akBaseObject == None || akBaseObject as Enchantment || akBaseObject == PreObj return endif ; OnObjectEquippedイベントを受け取らないようにする GotoState("Busy") ; 装備を記憶する PreObj = akBaseObject ; やりたいことをここに書く ; 装備の記憶を解除する PreObj = None ; OnObjectEquippedイベントを受け取るようにする GotoState("") EndEvent State Busy Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference) EndEvent EndState 解説 aksourceをas enchantmentでキャスト(変換)すると、エンチャントかどうかの判定になる。 エンチャントが武器より先に処理されてしまって肝心の武器のほうがBusyで除外されちゃうので、エンチャントは最初にリターンで中断。 PreObjに前回のオブジェクトを代入しておいて、前回と同じだったらリターンで中断。ほぼ同タイミングぐらいに処理されるのでBusyだけだと間に合わずにこれが必要。 OnHitの重複防止 OnHitはエンチャントなどで延焼させている場合に、延焼ダメージが攻撃した武器ダメージと同じ換算してしまう仕様なので、けっこう重複しやすいのです。 事前にソース元を代入して被ったら飛ばす仕組み。 Form PreSource = None Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) ;攻撃者がいない場合のエラー防止とダメージソースが武器以外はリターンで即処理中断 if akAggressor == None || !(akSource as Weapon) || akSource == PreSource return endif ;BusyのStateに飛ばす GotoState("Busy") ;PreSourceに今のダメージ元を代入 PreSource = akSource ;武器の種類を取得 int WeapType = (akSource as Weapon).GetWeaponType() ;両手剣または両手斧槌ならば if WeapType == 5 || WeapType == 6 Game.GetPlayer().DamageAV("Stamina",5.0) endif ;重複防止のため0.5秒待機 Utility.Wait(0.5) ;PreSourceをなしの状態に戻す PreSource = None ;Stateを元の状態に戻す GotoState("") EndEvent State Busy ;StateがBusyの時はOnHitイベントが起こっても何も処理しない Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked) EndEvent EndState スクリプトログをとる(デバッグの仕方) スクリプトログの設定 マイドキュメント\My Games\Skyrim\Skyrim.ini を開いて、以下の通りにしたあと保存。(項目がなければ追加) [Papyrus] bEnableLogging=1 bEnableTrace=1 bLoadDebugInformation=1 すると次回から マイドキュメント\My Games\Skyrim\Logs\Script にPapyrus.0.logというのが出ますのでメモ帳以外のテキストエディタで開くとデバッグの内容が見れます。 LogExpertを導入 リアルタイムでログが取れるツールです。 LogExpertをダウンロードします。 LogExpert.exeを起動します。 File→Openから、マイドキュメント\My Games\Skyrim\Logs\Script\Papyrus.0.logを開きます。 Options→Always on Topを押して、常に手前に表示にします。 Optionの下あたりにあるメニューのFollow Tailsにチェックを入れます。 スクリプトにデバッグ情報の記載 ログに書き出すにはDebug.Trace("文字")を使います。""のあとに+を使うと変数や関数の結果を書き出せます。 例: Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference) Debug.Trace("Debug FormName" + akBaseObject.GetName() ) EndEvent これでゲームとLogExpertを起動して、装備を付けたりすることでスクリプトの動作をリアルタイムで確認できます。 意図する結果になるまで以下の手順で実験してみてください。 スクリプトを書き直してコンパイル コンソールコマンドで reloadscript script名 OnAnimationEventで取得できるイベント RegisterForAnimationEventで登録したアニメーションイベント(モーション)をOnAnimationEventで取得することができますが、 取得できるのとできないのがあります。 ☓staggerStart ○staggerStop Start系のモーションは軒並みダメです。 Skyrim - Animation.bsaの中のmeshes\responses\actorresponse.txt というテキストファイルに記載されてるのが使用可能なアニメーションイベントです。 ブロックの動作はじめにイベントを受け取りたい場合にBlockStartだとダメですが、裏ワザ的なやり方があります。 SoundPlay.NPCHumanCombatShieldBlockです。 SoundPlay系は受け取れるので開始時にイベント取得したいなという時にSoundPlayのAnimeEventをあたってみるといいと思います。 Gameplay - Animations.. - AnimEventの選択項目でSoundPlayを探して手当たり次第試してみましょう。 使えそうなイベント一覧 MRh_SpellFire_Event 右手で魔法を放ったとき MLh_SpellFire_Event 左手で魔法を放ったとき arrowRelease 矢を放ったとき BowDrawn 最大限弓を引いたとき weaponSwing 右手の武器を振ったとき weaponLeftSwing 右手の武器を振ったとき preHitFrame 近接攻撃がヒットする直前 HitFrame 近接攻撃がヒットしたとき。当たらない場合も検出する BashExit バッシュしたとき BashStop バッシュしたとき BashRelease バッシュボタンを押し続けてバッシュが発動したとき。パワーバッシュは盾装備時のみ検出する RemoveCharacterControllerFromWorld ラグドール状態になった時 KillMoveStart キルムーブが発生した時。実行者及び被害者両方で検出されるため注意 Decapitate キルムーブ等で首を刎ねられた時 参考になりそうなサイト Creationkit.com プレイヤー動作時のAnimEventが動く順番 Withe01さんのMOD作成日誌 20130930-対人用KillMove一覧 Withe01さんのMOD作成日誌 AnimationEvent Withe01さんブログは主に動作をさせる(イベントを起こす)ときのことが書いてある。 AnimationVariableの使い方 スカイリムのモーションを司るHavok Behaviorが扱うアニメーション変数(AnimationVariable)を取得したり変更したりできます。 これを使うことによってActorに関して細かく状態を判定したり、制御したりできます。 この変数はActorの種類によって異なります。 例えばCharacter(人)だとIsStaggeringはありますが、Dragonにはありません。 どんなアニメーション変数が何があるのかは以下のスプレッドシートのデータを確認してください。 人のアニメーション変数とイベントデータ 人以外のアニメーション変数とイベントデータ そのほかは、Josh Behavior file patcherで確認ができます。 人ならbehaviorフォルダの0_master.hkx、ドラゴンならdragonbehavior.hkx。 関数: Get/SetAnimationVariableBool Get/SetAnimationVariableFloat Get/SetAnimationVariableInt これらのアニメーション関数はConditionでも使えます。 Condtionでの関数名はGetGraphVariableFloatとGetGraphVariableIntです。 例:GetGraphVariableInt "IsStaggering" == 1 ;BoolはIntで代用。1はtrue 0はfalse さまざまな状態の判定 Actor.GetAnimationVariableBool("xxx") 判定 xxxに記載する文字列 攻撃中 IsAttacking ブロック中 IsBlocking バッシュ中 IsBashing はじかれ中 IsRecoiling よろめき中 IsStaggering 抜刀中 IsEquipping 納刀中 IsUnequipping ジャンプ中 bInJumpState ブロック成功 IsBlockHit 例:Actor.GetAnimationVariableBool("IsAttacking") ;攻撃中、パワーアタックも含まれる 一人称視点かどうかの判定 player.GetAnimationVariableInt("i1stPerson") == 1 移動方向の判定 floatのDirectionを使います。 Actor.GetAnimationVariableFloat("Direction") == 0 ; forward 時計回りに0から1まで。 0 前と立ち状態 0.125 右斜め前 0.25 右 0.375 右斜め後 0.5 後ろ 0.625 左斜め後 0.75 左 0.875 左斜め前 コントローラーのアナログスティックはSKSEやScriptDragon(※ScriptDragonはAnimationVaribleが使えません)でも検知できないので、このDirectionを使います。 立ち状態と前とで区別つけるときは下の移動中判定と組み合わせてください。 移動中かどうかの判定 一見するとbInMoveStateなんですが、壮大なトラップで片手どちらかに魔法か杖を持ってると移動中でもFalseを返します。 代わりにSpeedを使います。 if Actor.GetAnimationVariableFloat("Speed") 5.0 ;停止中 iStateの変数 GetAnimationVariableInt("iState")で取得できる値はMovement Typeと連動していると思われます。 何ができるかというと、状態判定ができます。 例:パピルスにはIsBlockingがないので、以下のようにします。(上のIsBlockingを使ったほうが確実) if (Actor.GetAnimationVariableInt("iState") == 4) || (Actor.GetAnimationVariableInt("iState") == 17) 変数の数値が何を意味するかは以下の通り。 スプリント中 1 iState_NPCSprinting スニーク移動中 2 iState_NPCSneaking 弓・クロスボウ構え中、リロード中 3 iState_NPCBowDrawn ブロック中 4 iState_NPCBlocking ダウン中 5 iState_NPCBleedout 片手・素手移動中 6 iState_NPC1HM 両手移動中 7 iState_NPC2HM 弓・クロスボウ移動中 8 iState_NPCBow 魔法移動中・停止中 9 iState_NPCMagic 魔法・杖キャスト中 10 iState_NPCMagicCasting 騎乗時? 11 iState_NPCHorse 片手・素手攻撃中 12 iState_NPCAttacking 両手攻撃中 13 iState_NPCAttacking2H パワーアタック中 14 iState_NPCPowerAttacking 酩酊中? 15 iState_NPCDrunk 弓・クロスボウ構え中(QuickShot習得後) 16 iState_NPCBowDrawnQuickShot ブロックランナー取得後ブロック中 17 iState_NPCBlockingShieldCharge 騎乗時移動中 60 iState_HorseDefault 騎乗時スプリント中 61 iState_HorseSprint 騎乗時ジャンプ中 62 iState_HorseFall 騎乗時水泳中 63 iState_HorseSwim これはBehaviorファイルのBSiStateTaggingGeneratorという項目で指定してます。 iStateToSetAsで数値指定で、iPriorityが優先度です。 一部プレイヤーとNPCで違う模様。アクターによっても違います。 セーブデータに残るもの Save File Note(CK wiki) セーブするとセーブデータに保存されるものがあります。 グローバル変数 静的変数 プロパティ 一旦セーブされたデータでMODを更新したときにプロパティや静的変数などを削除した場合やMODを抜いた場合はセーブ内と一致しないのでログにエラーを吐きます。 エラーを吐くのですが、データがないと無視するので基本的に害はありません。 不必要になったプロパティの削除 プロパティはesp側にも紐ついてるので、そちらも消す必要があります。 スクリプトのついてるPropertyボタンを押してプロパティウィンドウを出します。 不要なプロパティのClear Valueを押して消してください。 そのあと、スクリプト側のプロパティの記述を消します。 espを保存します。 SM Eventを使ったRepeatQuest OnUpdateを使わずにループができるクエストの作り方です。 セル移動時関係のイベント セル移動時にスクリプトを動かしたいときにいくつかイベントがあるんですが、どれも癖があってそれを記したいと思います。 Onload 3Dオブジェクトがロードされるときに発生するイベントで、ロード画面が挟むセル移動でなら起きます。 ただしセルを移動してすぐ戻る場合はセル移動時にロード挟まないのでその場合は発生しません。 プレイヤーは稼働しません。 OnAttachedToCell セルからセルに移動するときに発生するイベントです。 たとえばワールドTamrielのWildness1からWildness2に移動するときにも発生します。 ただしプレイヤーは稼働しません。 またスカイリムからホワイトランに入るときには動きません。(逆は動くので条件不明) OnLocationChange ロケーションの移動時に動くイベントですが、複数のセルをまとめて一つのロケーションとして扱う場合があって、例えばホワイトラン→スカイリム、スカイリム→ホワイトランは動きません。 ですので一般的にセル移動時判定には向いてません。 OnCellLoad セルロード時にイベントが発生しますが、メモリキャッシュ済みのセルの場合は発生しません。 続けてゲームプレイする場合に一度入ったセルにもう一度入った場合に発生しない可能性が高いです。 プレイヤー(エイリアス)に使えます。 NPCであれば、Onloadをおすすめします。 プレイヤーは厳密さを要求しないのであれば、OnCellLoadで大抵何とかなります。 NPCへのPerk付与について オススメはSPIDを使ったゲーム起動時のPerk付与です。 スクリプトのAddPerk関数 プレイヤーに対しては正常に機能しますが、NPCに対しては全く機能しません。 コンソールのAddPerkコマンド スクリプトのAddPerk関数と同様、プレイヤーに対してのみ正常に機能します。 マジックエフェクトの"Perk to Apply" スクリプトのAddPerk関数と同様、プレイヤーに対してのみ正常に機能します。 CKやxEditにて事前にPerkを持たせる プラグインを作成して事前にPerkを持たせておけば確実ですが、レコードの競合等により不具合が起こる危険性があります。 Spell Perk Item Distributor (SPID) にてゲーム起動時にPerkを持たせる NPCに事前にPerkを持たせておくことができるというSKSEプラグイン(LE/SE)です。ゲーム起動時にあたかもはじめから所持していたかのように処理されるため、レコードが競合する心配がありません。 powerofthree's Papyrus ExtenderのAddBasePerk関数 スクリプトでNPCへPerkの付与が可能になるSKSEプラグイン(LE / SE)です。いまのところゲーム中でPerkを付与する唯一の方法となります。 パークを付与する ; targetActorに対象のActor、addPerkに付与させたいPerkを渡す po3_sksefunctions.AddBasePerk(targetActor, addPerk) 付与したパークを消す po3_sksefunctions.RemoveBasePerk(targetActor, addPerk) ただし、powerofthree's Papyrus Extenderのパーク付与は以下の問題点もあるため、使用する場合は付与状況の監視が必要となります。 ※現状だと問題点あり NPCにパーク付与後に『対象NPCがパーク付与前かつセルにロードされている』セーブデータをロードするとセーブ時点でパーク未付与前のNPCにパークが付与される NPCにパーク付与後にNPCがセルからアンロードされた状態で保存した後にスカイリムを終了させ、再度起動してタイトルからロードした場合、ロード後のパーク付与がNPCに適用されない(正確にはセーブ時にAddBasePerkで何を追加されたかを保存するのだが、対象のNPCがアンロードされてると保存されない) 同一のアクターに二回以上AddBasePerkを行うと最初にAddBasePerkで付与したパークが再付与され二重に適用される(disable→enableで正常に戻る) → 4.5.2で修正 Perkの挙動について 追加Perk系のModを制作する時には特に下記の点に注意する事。 特定行動時にスペル付与系 Apply Combat Hit SpellやApply Weapon Swing Spellなど、 特定行動時にスペル効果を付与するパークについて条件を満たしたものが複数ある場合、 Priorityが0に近いパークのスペル効果のみが付与されます。 例として両手武器のウォーマスター(後ろパワーアタックで麻痺効果付与)はPriorityが0、出血攻撃(両手斧攻撃で出血状態付与)はPriorityは3~10が設定されており、 この場合、両手斧で後ろパワーアタックを行った場合はウォーマスターの効果が優先され出血攻撃の効果は出ません。 攻撃時やヒット時に魔法効果を付与といったものを作成したい場合、下手にパークのApply Combat Hit SpellやApply Weapon Swing Spellを使うとバニラのパークを含めて上手く動作しなくなる可能性が高いため、スクリプトで処理を行うことをオススメします。 なおこの制限についてはScrambled BugsというSKSEプラグインを導入して、ScrambledBugs.jsonのmultipleSpellsをtrueにする事で解除は可能です。 (制限解除時だと上の例にある両手斧で後ろパワーアタックで麻痺効果と出血攻撃の両方の効果が付与される) Add ValueやSet Value等の数値変動系の計算の優先度 バニラのクリティカル率や同時付呪数を変更するパークを確認するとEntry PointのFunctionがSet Value(絶対値)となっています。もし、クリティカル率が増減するパークを作成したい時に下記のようにAとBのパーク両方を保持した際に絶対値の後に計算されるのか疑問に思った人はいるはずです。 A. クリティカル率(Calculate My Critical Hit Chance)の値をSet Valueで設定 B. クリティカル率の値をAdd ValueやMultiply Valueで変動 結論としてAとBのパークについてどちらも保持した場合、Priorityの数値が高いパークから先に適応され計算されます。 Priorityが同値の場合はFormIDが大きい方から先に適応されます。 例: ※AのSet Valueが25、BはAdd Valueで50を設定していた場合 AのPriorityが0で、BのPriorityが1の場合:Bの数値設定でどれほど値を変動させてもAの数値となる(25) AのPriorityが1で、BのPriorityが0の場合:Aの数値に対してBの設定値で変動したものが最終的な値(75) AとBのPriorityが同値:FormIDが大きいものから先に適応 そして、クリティカル率が変動するパーク(片手武器の剣士等)、追加付呪のパークはSet Valueで値を固定されていてなおかつPriorityが0となっています。このため、クリティカル率の増減、または同時付呪数の増減パークをModで作成してもバニラのパークを所有した瞬間、Mod追加パークの効果が正常に反映されなくなってしまいます。 解決策として、追加付呪等の一部を除いたパークは非公式パッチ(SEのUSSEPで確認)でAdd Valueに修正されているため、非公式パッチを前提Modとして作成する必要があります。 非公式パッチを前提Modにしない場合は修正用espを別途作成し、「剣士(片手武器パーク)、深手(両手武器パーク)、クリティカルショット(弓パーク)、追加付呪(付呪パーク)」のEntry PointのFunctionをAdd Valueに修正する必要があります。 IsInKillMove関数の注意点 IsInKillMoveはアクターがキルムーブを実行中、またはキルムーブを受けてる最中の場合にもtrueを返すため、キルムーブの実行者か受けてる側かの判定はOnHitイベント(キルムーブの一撃でもHitイベントは発生する)やOnDyingイベント(キルムーブを受けてる最中に発生)を併用する必要があります。 スクリプトによる一部のフォームの値変更について SpellやArmor、Weapon等のベースフォームについてSet~関数等で値を変更しても一時的な値変更と扱われるためセーブデータに保存されません。(ActorBaseの関数もSetEssential等はセーブデータに保存されるが一部は一時的な変更になるものも存在する) また、一時的な値変更となるものに関してはゲームを再起動するまではリセットされないため、値変更後に変更前のセーブデータをロードしても値は変更後のままになります。 ConsoleUtilによるターゲットコマンド実行の注意点及び安全な実行について 負荷が掛かると誤実行される危険性がある ConsoleUtilでターゲットコマンド(SetAVやSetLevel等)を実行する場合、SetSelectedReference関数を使って対象の選択をすると思いますがSetSelectedReference関数にはコマンドの実行まで対象の切り替えを抑止する機能はありません。 ConsoleUtilを使ってるModが一つだけなら問題ないのですが複数のModがConsoleUtilでターゲットコマンドを使ってる場合は注意が必要です。 もしConsoleUtilを使ってるスクリプトの処理が重なるような事が起こった時にコマンド実行直前で別のスクリプトのSetSelectedReference関数で対象が変更される可能性があり指定していない対象に対してターゲットコマンドの誤実行が行われる危険性があります。(特にスクリプト遅延が起こってる状態では高確率で発生します) 対策 これに対する回避策としてターゲットコマンドを行う場合、下記のサンプルのようにコマンド文を "[ID]".[コマンド]にする事でコンソールの選択対象に関係無く[ID]の対象に対してコマンドを実行されます。 こうする事により指定した対象以外への誤実行を防ぐ事ができます。 ; ターゲットコマンドの安全実行 ; SetSelectedReference→ExecuteCommandの順で実行する場合、複数のスクリプトがConsoleUtilを使ってると、 ; コマンドが指定していない対象に対して誤実行される危険性があるため ; コマンド文を"[ID]".[コマンド]に変換し、コマンド実行を指定した対象に対して確実に行うようにする ; 数値の16進数文字変換はpowerofthree`s Papyrus ExtenderのSKSE関数を使用 function SafeTargetCommandExecute(string cmd, Form target) if target ; IDをダブルクォートで囲まないとIDに英文字が混ざってない場合にエラーが起こる cmd = "\"" + PO3_SKSEFunctions.IntToString(target.getFormID(), true) + "\"." + cmd else Debug.trace("Console Command Target is None " + cmd, 2) return endif ConsoleUtil.ExecuteCommand(cmd) endfunction アビリティ付与に関する注意 SPIDやスクリプト等でNPCに何かしらのアビリティを直接持たせた場合、NPCをテレポートしたり内部セルへ移動する等何かしらの要因で偶にアビリティに付属してる魔法効果が消滅するという現象が発生します。 アビリティに付属した魔法効果が消えた場合はアビリティの再付与を行わない限りは魔法効果が復活しません。 この現象はパーク効果にアビリティが付属してるものをNPCに持たせた場合は発生しません。アビリティをNPCに直接持たせた場合にのみに発生します。 (パークに付属したアビリティはゲームエンジンレベルで魔法効果が機能してるかチェックしてる?) そのためスクリプト付きアビリティをプレイヤーやNPCに配布するModを作成する場合、確実にアビリティを持たせて機能させたければダミーパークにアビリティを付属させてそのパークを付与させるようにしましょう。 Activate関係の処理について BlockActivation関数でアクティベートをブロックしてもOnActivateイベントは発生する アクター等に対してBlockActivation関数を実行した場合、 対象をアクティベートしても見た目上は反応が返ってきませんが、この時OnActivateイベントはしっかり発生します。 これはスクリプトのActivate関数で第ニ引数にfalseを渡してアクティベートがブロックされた際も同様です。 パークのアクティベート処理変更についての注意点 パークのEntry PointでActivateを設定してReplace Defaultにチェックを付けると 対象のアクティベート時に本来の動作の代わりにパークに付属したスクリプトの処理にすげ替える事ができます。 しかし、このアクティベートの動作変更を使用する場合は下記の点を考慮する必要があり、 特に下記の上2つの現象についてはちゃんと対処しておかないと 他のアクティベート関係の処理が行われるModと一緒に使用した場合に問題が発生する可能性があります。 (上2つの現象はEFFで確認が可能です) OnActivateイベントが発生しない 本来ならばアクティベートした瞬間にOnActivateイベントが発生するのですが パークによるアクティベート処理をスクリプト処理に挿げ替えてる場合はOnActivateイベントが発生しません。 アクティベート処理変更を行いつつOnActivateイベントを発生させたい場合は スクリプト処理内で対象に対してActivate関数を使用する事でOnActivateイベントを発生させられます。 デフォルトのアクティベート処理を実行させずに スクリプト処理だけ実行してOnActivateイベントを発生させたい場合は blockActivation関数でアクティベートをブロック後にActivate関数(第二引数はfalse)を実行し 再度blockActivation関数でブロック解除を行う必要があります。 スクリプト処理後にデフォルトのアクティベート処理を実行をする場合は blockActivation関数は使用せずに スクリプトの最後にActivate関数を実行すればよいだけです。 なお、Activate関数の第ニ引数をtrueを渡した場合はOnActivateイベントは発生しないので注意しましょう。 BlockActivation関数でアクティベートのブロックをしても処理が実行される BlockActivation関数によるアクティベートのブロックについては デフォルトのアクティベート動作のみが対象となり、 アクティベート処理をスクリプト処理に挿げ替えた場合は下記のようにスクリプト側で対象が アクティベートブロック状態かをチェックして抑制しないとそのままスクリプト処理が実行されてしまいます。 if akTargetRef.isActivationBlocked()returnendif スクリプト側でアクティベートした場合は動作変更が行われない パークによるアクティベート変更はゲーム内で直接アクティベートした場合のみ有効で スクリプトでActivate関数を呼び出した場合はデフォルトのアクティベート処理が行われます。 対処法のサンプル 上記のOnActivateイベントとblockActivation関数による抑制による スクリプトのサンプルは下記の通りとなります。 ; パークによるアクティベート動作変更時に; blockActivation関数によるアクティベートのブロックをしてる時に; 処理を実行しないようにしたり、; OnActivateイベントを発生させるためのサンプル; Fragment_2の関数名は環境によって異なるはずなので注意Function Fragment_2(ObjectReference akTargetRef, Actor akActor); パークによるアクティベート動作変更時は; スクリプト側でブロックしないとそのまま処理されてしまうif akTargetRef.isActivationBlocked();OnActivateイベントを発生させるakTargetRef.activate(akActor, false);Debug.trace("Block Activate")returnendif ; 以下~~~にアクティベート時に行う処理を記述する~~~~ ; パークによるアクティベート動作変更時はOnActivateイベントが発生しない; アクティベート対象に対してActivate関数を使用すればOnActivateイベントを発生させられるが; デフォルトのアクティベート処理まで実行してしまうため; blockActivation関数でデフォルトのアクティベート処理をブロックし、; Activate関数を使用後、再びブロックを解除するようにする; ; 処理後にデフォルトのアクティベート処理をしたい場合は; blockActivationはコメントアウトするakTargetRef.blockActivation(true);akTargetRef.activate(akActor, false);akTargetRef.blockActivation(false);EndFunction
https://w.atwiki.jp/wrtb/pages/489.html
WRTB 06 ランピーによる矛盾 前回、『くまのプーさん』シリーズのエピソードに関する矛盾を紹介しました。 さて、今回はズオウ*に関する矛盾です。 ズオウといえば、謎の生物であり、プー達が恐ろしいはちみつ泥棒の怪物だと恐れる対象としてたびたび登場します。どの物語においても、ズオウは実は架空の生物だった、または2足歩行のただのゾウだった、というオチで締め括られています。『プーさんと大あらし』(1968年)をはじめ、ほとんどといってもいいほどの回で登場しています。 しかし、『くまのプーさん ザ・ムービー はじめまして、ランピー!』(2005年)に登場したズオウのランピー*がルーと友達になってしまったため(しかも、それが一回性ではなく後の作品にもランピーが登場する)、この手のズオウ・エピソードが登場しなくなってしまいました。このズオウの役割はTVシリーズ『プーさんといっしょ*』(2007年~)ではヒイタチ*が引き継いでいるようです。 ズオウに関して矛盾が生じているのは、この『はじめまして、ランピー!』なのです。ルーはプー達に初めてズオウの存在を知らされ、翌日にはズオウが良い生き物だということを知るのです。では、今までの37年間に作られたルーが「ズオウは怖い生き物だ」と認識していたエピソードはどうなるのでしょうか。つまり、後のズオウの存在意義を変えてしまったこの作品は、今までの常識を指一本で根底から覆してしまった衝撃の作品だったのです。よって、この作品は古来のファンからはあまり良い評価が下されないんだとか。